          PH.ARGS DRPT,BRCHS,BR,SD,ED,SELECT1,SELECT2,SEL.TYP,SORT.LVL,COST.DATA,OPT,STAT,FITEM,SBR,INCLUDE.DATA
** Version# 154.0503[3] - 02/18/2010 - 05:12pm - SMITJR - eclipse
** Copied from UBP SLS.PHR.PROD.SUM.TEST Version# 154.0502[1] - 02/16/2010 - 10:41pm - SMITJR - eclipse
*** V154.0503 Change - Custom Coding CUSTOM - 02/18/2010 - SMITJR - eclipse
** Copied from BP SLS.PHR.PROD.SUM.TEST Version# 154.0501 - 05/04/2007 - 10:16am - EILEENM - r8.0emr
*** V154.0501 Change - No Develop Ver Yet HGY624 - 05/04/2007 - EILEENM - r8.0emr
*** V154.05 Change - No Develop Ver Yet HGM417 - 04/04/2007 - BABS - r8.0base
*** V154.04 Change - No Develop Ver Yet CQS896 - 03/07/2007 - ANNEM - r8.0base
*** V154.03 Change - No Develop Ver Yet CQS896 - 03/07/2007 - ANNEM - r8.0base
*** V154.02 Change - No Develop Ver Yet AVP269 - 12/12/2006 - KRISTIS - r8.0base
*** V154.01 Change - No Develop Ver Yet AVP269 - 11/09/2006 - KRISTIS - r8.0base


*** Program - SLS.PHR.PROD.SUM
*-------------------------------------------------------------------------*
*** This routine is the PHANTOM for the Product Sales Report. It wil print
*** a report of all products that were sold within a specified date range,
*** and that match any criteria specified by the User from the Driver.
*-------------------------------------------------------------------------*
*** DRPT         - Dynamic array of Driver program and print/hold     [IN]
***                options.
*** BRCHS        - Branch(es) user is running report for.             [IN]
***                > Only invoices having these Branches will be
***                  included on the report.
*** BR           - Literal entered for the branch prompt.             [IN]
*** SD           - Start Date. Only Products sold on or after this    [IN]
***                date will be included.
*** ED           - End Date. Only Products sold on or before this     [IN]
***                date will be included on the report.
*** SELECT1      - Select by option and Select by entities.           (IN)
***                > The Select by option is ALWAYS the first
***                  Value in the array. All subsequent Values are
***                  Select by entities chosen, and will ALWAYS
***                  be null if the first Value is.
*** SELECT2      - Additional Select option and Additional Select     (IN)
***                entities.
***                > The Additional Select option is ALWAYS the first
***                  Value in the array. All subsequent Values are
***                  the Additional Select entities, and will ALWAYS
***                  be null if the first Value is.
*** SEL.TYP      - Product Location type to SELECT records for.       [IN]
***                > S - Stock
***                > O - Over Shipment
***                > F - DeFective
***                > R - Review
***                > L - Display
***                > T - Tagged
*** SORT.LVL     - Multi-Valued -> SortBy and Customer Level          [IN]
***                > Cust. Level can be 'BillTo', 'ShipTo' or 'Parent'
***                > and tells the report which Customer to display
***                > data for.
*** COST.DATA    - Multi-Valued -> Cost Type and Show Costs flag      (IN)
***                > If the Show Costs flag is set to 'No', Cost data
***                > will NOT display on the report.
***                Cost Types:
***                 > 1 - COMM Costs.
***                 > 2 - COGS
***                 > 3 - None
*** OPT          - Summary or Detail Format for the report, Page      [IN]
***                break
*** STAT         - Product Status to SELECT records for.              [IN]
*** FITEM        - 'Additional' select criteria. This is standard on  (IN)
***                any reports building off the Ledger File.
*** INCLUDE.DATA - Multi-Valued list containing flags for             (IN)
***                Including/Excluding/Only showing Transfers, Credits,
***                Directs, Vendor Consigments, Customer Consignments,
***                Serial Numbers and Kit Components.
*-------------------------------------------------------------------------*
*** COMMON Variables Used: LED, LD, PRD, CUS
*-------------------------------------------------------------------------*
          *** Go initialize the date we'll need to run this program, parse
          *** out data from our parameter list, open the SALES.BUDGET.GRP
          *** File and create a Tempfile to store our report data in...
          GOSUB INIT

*-------------------------------------------------------------------------*
          *** Update the Phantom Status...
          WRITE 'Selecting...' ON PHSTFILE,PID$

          *** Go try and Select data for the Report...
          GOSUB SEL.IDS
          *** Update the Phantom Status...
          WRITE 'Spooling...' ON PHSTFILE,PID$
*-------------------------------------------------------------------------*

          *** Go Build our Report Heading...
          GOSUB SET.HEADING

*** Turn our printer on and print out all the records we selected...
          PRINTER.ON WIDTH,TITLE,DOC.ID,HDG,RPT.DFLT=DRPT
          FILTER.PRINT "S",FITEM

          *** Initialize more variables...
          CCT         = 0
          STOL        = ''
          CTOL        = ''
          BTOL        = ''
          GTOL        = ''
          PREV.CN     = '@@@'
          PREV.TID    = '@@@'
          PREV.SELL   = '@@@'
          PREV.TD2    = '@@@'
          PREV.BUDG   = '@@@'
          PREV.COM.CD = '@@@'
          PREV.PROD   = '@@@'
          PN.LIST     = ''
          UM.LIST     = ''

          SSELECT TEMPFILE
          *** Loop through each line and print the data
          LOOP
             READNEXT TID ELSE EXIT
             READ TMP FROM TEMPFILE,TID ELSE TMP = ''
             TID2 = FIELD(TID,'|',2)

             BEGIN CASE
             CASE BUDGET.SORT
                BUDG      = TID2
                BUDG.CN   = FIELD(TID,'|',3)
             CASE COMMODITY.SORT
                COM.CD.CN = TID2
                COM.CD    = FIELD(TID,'|',3)
             CASE SELL.SORT
                SELL      = TID2
                SELL.CN   = FIELD(TID, '|',3)
             CASE PRODUCT.SORT
                PROD      = TID2
             END CASE

             TID1 = FIELD(TID,'|',1)

             *** Print branch and subtotals if needed...

             IF SEL.SORTBY[1,2] = 'Br' THEN
                IF SEL.SORTBY = 'Branch by Price Line' THEN
                   IF TID1 # PREV.TID THEN
                      GOSUB PRT.BTOL
                      GOSUB PRT.STOL
                   END ELSE
                      IF TID2 # PREV.TD2 THEN GOSUB PRT.BTOL
                   END
                END ELSE
                   IF TID1 # PREV.TID THEN
                      GOSUB PRT.STOL
                   END
                END
             END ELSE
                BEGIN CASE
                CASE BUDGET.SORT
                   IF BUDG # PREV.BUDG THEN
                      PREV.TID  = PREV.BUDG
                      GOSUB PRT.STOL
                   END
                CASE COMMODITY.SORT
                   IF COM.CD # PREV.COM.CD THEN
                      PREV.TID  = PREV.COM.CD
                      GOSUB PRT.STOL
                   END
                CASE SELL.SORT
                   IF SELL # PREV.SELL THEN
                      PREV.TID  = PREV.SELL
                      GOSUB PRT.STOL
                   END
                CASE PRODUCT.SORT
                   IF PROD # PREV.PROD THEN
                      PREV.TID  = PREV.PROD
                      GOSUB PRT.STOL
                   END
                CASE SEL.SORTBY = 'Product'
                   IF TID2 # PREV.TID THEN GOSUB PRT.STOL
                   PREV.TID = TID2
                CASE OTHERWISE
                   IF TID1 # PREV.TID THEN GOSUB PRT.STOL
                END CASE
             END

             *** Print the line...
             PREV.BUDG   = BUDG
             PREV.COM.CD = COM.CD
             PREV.SELL   = SELL
             PREV.PROD   = PROD
             *** Go print a line of the report...
             GOSUB PRT.ONE
          REPEAT

*** If necessary, go print Branch Totals...
          IF SEL.SORTBY[1,2] = 'Br' THEN
             GOSUB PRT.BTOL
          END

*** Go print Sortby Subtotals...
          GOSUB PRT.STOL

*** If necessary, go print Customer Totals...
          IF SEL.SORTBY[1,3] = 'Cus' AND NOT(PO.FLAG) THEN
             IF CCT > 1 OR NOT(DETAIL) THEN GOSUB PRT.CTOL
          END

*** Go print the Grand Totals...
          GOSUB PRT.GTOL

*** Turn the printer off and clean up after ourselves...
          PRINTER.OFF DOC.ID
          UT.TEMPFILE.DELETE FLNM.ID
          UT.PH.CLEANUP

          IF ITEM.CT = 0 THEN
             COUNT.MSG = ' - No Items Found'
          END ELSE
             COUNT.MSG = ' - is Complete'
          END

          SEND.MESSAGE 'Phantom',USER.ID,TITLE:COUNT.MSG

          STOP
*-------------------------------------------------------------------------*
INIT:     *** Initialize the date we'll need to run this program, parse
          *** out data from our parameter list, open the SALES.BUDGET.GRP
          *** File and create a Tempfile to store our report data in...

*** Parse out date from the parameters passed in...
          *** Page breat/option...
          PG.BRK    = OPT<1,2>
          OPT       = OPT<1,1>

          *** Show Costs flag and Cost Type...
          COST.TYPE = COST.DATA<1,1>
          COSTS     = COST.DATA<1,2> ; * Show Costs flag

          IF COSTS  = 'N' OR COST.TYPE = 3 THEN COST.TYPE = ''
          PH.COST.DESC COST.TYPE,COST.DESC

          *** Break out the items that are to be
          *** Included/Excluded/Only shown...
          INC.ITEMS  = FIELD(INCLUDE.DATA,'~',1)

          SHOW.STOCK   = INC.ITEMS<1,1>
          SEL.TRANS    = INC.ITEMS<1,2>
          SEL.CREDS    = INC.ITEMS<1,3>
          SHOW.DIR     = INC.ITEMS<1,4>
          SHOW.VCSN    = INC.ITEMS<1,5>
          SHOW.CCSN    = INC.ITEMS<1,6>
          SHOW.VENCUST = INC.ITEMS<1,7>
          VEN.ID       = INC.ITEMS<1,8>
          CUS.ID       = INC.ITEMS<1,9>

          *** Break out our flags for showing Serial Numbers
          *** and Kit Components...
          SHOW.SNS       = FIELD(INCLUDE.DATA,'~',2)
          SHOW.KIT.COMPS = FIELD(INCLUDE.DATA,'~',3)
          FILTER.COMPS   = (SHOW.KIT.COMPS='Yes' OR SHOW.KIT.COMPS='Only')

          *** Break out the Sortby option and the Customer Level...
          SEL.SORTBY = SORT.LVL<1,1>
          LEVEL      = SORT.LVL<1,2>

          *** Break out the Select options...
          SLCT      = SELECT1<1,1>
          SLIST     = DELETE(SELECT1,1,1)

          *** Count the number of items they're selecting on...
          SEL.CT    = DCOUNT(SLIST,VM)

          ADDL.SLCT = SELECT2<1,1>
          SLIST2    = DELETE(SELECT2,1,1)

*** Initialize other variables that we'll be using...
          ITEM.CT  = 0
          FLAG     = ''
          SRT.BRK  = ''
          *** See if an ALTERNATE currency to be used has been passed in...
          TGT      = ''
          CURR.FLG = NO
          BASE.CUR = YES
          IF DRPT<51> THEN
             READ BASEC FROM CTRLFILE,"BASE.CURRENCY" ELSE BASEC = ''
             IF DRPT<51> # BASEC THEN
                TGT      = DRPT<51>
                CURR.FLG = YES
                BASE.CUR = NO
             END
          END

          *** Need ATTRIBUTES for filtering against Product Statuses...
          STAT    = RAISE(STAT)

          READV AR.PNS FROM CTRLFILE,'AR.LOAD.PN',1 ELSE AR.PNS = ''
          BUD.GRP = ''

          *** Values needed for Selecting AR Records...
          EQU INV.CD   TO 1 ; * Sales Orders
          EQU TRANS.CD TO 5 ; * Transfer Orders
          EQU ADJMT.CD TO 10; * Inventory Adjustments used for VConsign

          DETAIL = (OPT[1,1] = 'D')
          *** If the report is NOT printing in Detail format
          *** we will cannot display serial numbers...
          IF NOT(DETAIL) THEN SHOW.SNS = 'N'

          *** This will allow us to select different
          *** types of records using an Index...
          BEGIN CASE
          CASE SEL.TRANS[1,1] = 'E'
             JLI.CODES = INV.CD
             CD.CT     = 1
          CASE SEL.TRANS[1,1] = 'O'
             JLI.CODES = TRANS.CD
             CD.CT     = 1
          CASE OTHERWISE
             JLI.CODES = INV.CD:AM:TRANS.CD
             CD.CT     = 2
          END CASE

          * If vendor consignment is included need to include
          * inventory adjustments in the display
          IF SHOW.VCSN # 'Exclude' THEN
             JLI.CODES = JLI.CODES:AM:ADJMT.CD
             CD.CT    += 1
          END

          BUDGET.SORT    = NO
          COMMODITY.SORT = NO
          SELL.SORT      = NO
          PRODUCT.SORT   = NO
          BEGIN CASE
          CASE SEL.SORTBY[13,4] = 'Budg'
             BUDGET.SORT    = YES
          CASE SEL.SORTBY[13,4] = 'Comm'
             COMMODITY.SORT = YES
          CASE SEL.SORTBY[13,4] = 'Sell'
             SELL.SORT = YES
          CASE SEL.SORTBY[13,4] = 'Prod'
             PRODUCT.SORT = YES
          END CASE

          IF FITEM = '' THEN FILTER.FLAG = NO ELSE FILTER.FLAG = YES

          BRS = BR

          SDT = OCONV(SD,'D4/')
          EDT = OCONV(ED,'D4/')

          *** If user sorted by Customer, specify
          *** which type for the heading...
          BEGIN CASE
          CASE LEVEL[1,1] = 'B'
             LVL = 'Bill To '
          CASE LEVEL[1,1] = 'S'
             LVL = 'Ship To '
          CASE LEVEL[1,1] = 'P'
             LVL = 'Parent '
          CASE OTHERWISE
             LVL = ''
          END CASE

          *** Flag - if they wanted to Sort by 'Cust PO#'...
          PO.FLAG = (SEL.SORTBY[6,3] = 'PO#')

          *** Qty Types...
          SEL.TYPS = SEL.TYP
          CONVERT ',' TO VM IN SEL.TYPS

          SORTBY.MSG = ' by ':LVL:SEL.SORTBY:' '
          STOCK.MSG  = SHOW.STOCK[1,1]:"-Stock/Non-Stock"
          TRANS.MSG  = SEL.TRANS[1,1]:"-Transfers"
          CRED.MSG   = SEL.CREDS[1,1]:"-Credits"
          DIR.MSG    = SHOW.DIR[1,1]: "-Direct Shpmts"
          CCSN.MSG   = SHOW.CCSN[1,1]:"-Cnsign Billgs"
          VCSN.MSG   = SHOW.VCSN[1,1]:"-Vend Cnsigned"
          VENCUST.MSG= SHOW.VENCUST[1,1]:"-Vend/Cust Cnsigned"
          SEL.TRANS  = SEL.TRANS[1,1]
          SEL.CREDS  = SEL.CREDS[1,1]
          IS.CRED    = (SEL.CREDS = "I" OR SEL.CREDS = "O")

          ** Get the status message.
          IF DCOUNT(STAT,@AM) > 1 THEN
             STAT.MSG = 'Multiple Statuses'
          END ELSE
             READ TEMP FROM CTRLFILE,'PROD.STATUS' ELSE TEMP = ''
             STAT.MSG = 'Status: ':TEMP<1,STAT>
          END

          IF DETAIL THEN DET.MSG = 'Detail' ELSE DET.MSG = 'Summary'

*** Open the Sales Budget Group File and create a Tempfile...
          UT.OPEN.COMMON.FILE 'SALES.BUDGET.GRP', HNDL
          IF HNDL > 0 THEN
             BUDFILE = FILES(HNDL)
          END ELSE
             SEND.MESSAGE 'Phantom',USER.ID,'Cannot open SALES.BUDGET.GRP'
          END

*** Create a Tempfile to store our Report data in...
          UT.TEMPFILE.CREATE FLNM.ID,TEMPFILE
          RETURN
*-------------------------------------------------------------------------*
SET.HEADING: *** Build the part of the report Heading that we'll
             *** use regardless of whether we're creating a Detail
             *** or Summary Report...

*** Set up the Heading for the report...
          HDG = 'Product Sales ':DET.MSG:SORTBY.MSG:' for ':SDT:' to ':EDT
          HDG<1,3>  = STOCK.MSG:'  ':TRANS.MSG:'  ':CRED.MSG:'  '
          HDG<1,3> := DIR.MSG:'  ':CCSN.MSG:'  ':VCSN.MSG:'  ':VENCUST.MSG

          *** Set up message for what serial numbers, if any,
          *** will be on the report...
          BEGIN CASE
          CASE SHOW.SNS = 'I'
             HDG<1,3>  := '  ':'Inbound Serial Numbers'
          CASE SHOW.SNS = 'A'
             HDG<1,3>  := '  ':'All Serial Numbers'
          END CASE

          IF CURR.FLG THEN
             HDG<1,3>  := '  ':'Report Currency:  ':TGT
          END

          IF (VEN.ID # "") THEN
             VEN.NAME = OCONV(VEN.ID,"TENTITY;X;1;1")
             HDG<1,4> = "Consignment Vendor: ":VEN.NAME "L#20"
          END

          IF (CUS.ID # "") THEN
             IF (VEN.ID # "") THEN
                HDG<1,4> := "   "
             END
             CUS.NAME  = OCONV(CUS.ID,"TENTITY;X;1;1")
             HDG<1,4> := "Consignment Customer: ":CUS.NAME "L#20"
          END

          SUB.FLAG = YES
          THDR     = ''
          HDR.LN   = 5

          *** If the User did a Select by...
          IF SEL.CT THEN
             IF SEL.CT > 1 THEN
                WRK      = '*Multi*'
             END ELSE
                WRK      = SLIST
                SUB.FLAG = NO
             END
             THDR := 'Select by ':SLCT:'(s): ':WRK
          END

          *** If there was an Additional Select made...
          IF SLIST2 THEN
             IF DCOUNT(SLIST2,VM) > 1 THEN
                WRK      = '*Multi*'
             END ELSE
                WRK      = SLIST2
             END
             IF THDR # '' THEN THDR := ' - '
             THDR := ADDL.SLCT:'(s): ':WRK
          END

          IF SEL.TYP THEN
             IF DCOUNT(SEL.TYP,VM) > 1 THEN
                WRK = '*Multi*'
             END ELSE
                WRK = SEL.TYP
             END
             IF THDR # '' THEN THDR := ' - '
             THDR := 'Qty Type(s): ':WRK
          END

          IF STAT.MSG THEN
             IF THDR # '' THEN THDR := ' - '
             THDR := STAT.MSG
          END

          IF FILTER.COMPS THEN
             IF SHOW.KIT.COMPS = 'Only' THEN
                WRK = 'Kit Components Only'
             END ELSE
                WRK = 'Show Kits as Components'
             END
             IF THDR # '' THEN THDR := ' - '
             THDR  := WRK
          END

          *** Stick the temp header (THDR) into our Heading...
          IF THDR THEN
             HDG<1,HDR.LN> = THDR
             HDR.LN += 1
          END

          END.HD = '   Qty Shipped'

          IF COSTS # 'O' THEN
             END.HD := ' Ext Amount......'
          END

          IF COST.TYPE THEN
             END.HD := '  Ext ':COST.DESC"L#4":'........  '
             IF COSTS #'O' THEN
                END.HD := 'GP$..........  GP%....'
             END
          END

          POSP = 0

          *** Part of our Report Heading will be different depending on
          *** whether we're printing a Detail or Summary Report. Go build
          *** that section now...
          IF DETAIL THEN GOSUB DET.HDG; ELSE GOSUB SUM.HDG

          IF DRPT<33> = '' THEN
             TITLE = 'Product Sales ':DET.MSG:' for ':SDT:' to ':EDT
          END ELSE
             TITLE = DRPT<33>:' - ':SDT:' to ':EDT
          END

          *** Calculate the width of report header
          WIDTH = MAXIMUM(LENS(HDG<1>))

          *** Tack on our Page Number to the first Heading line...
          HDG1.WDTH = LEN(HDG<1,1>)
          HDG<1,1> := SPACE(WIDTH - HDG1.WDTH - 12):'Page :^#####'

          BRANCH.ALLOW = (WIDTH - 21)
          IF LEN(BRS) > BRANCH.ALLOW THEN BRS = BRS[1,BRANCH.ALLOW]:'...'
          HDG<1,2>  = SBR:' Branche(s):  ':BRS

          RETURN
*-------------------------------------------------------------------------*
DET.HDG:  *** Build the Detail format column headings...
          CUST.HD = 'Cust #  Customer Name.............  Invoice#......  '
          WHS.HD  = 'Whs. ShipDate  Prod No..  Product........................ '

          BEGIN CASE
          CASE SEL.SORTBY  = 'Cust PO#'
             HDG<1,HDR.LN> = CUST.HD:'Cust PO#....... ':WHS.HD
             POSP = 16
          CASE OTHERWISE
             HDG<1,HDR.LN> = CUST.HD:WHS.HD
          END CASE

          HDG<1,HDR.LN>   := END.HD

          RETURN
*-------------------------------------------------------------------------*
SUM.HDG:  *** Build the Summary format column headings...
          HDG<1,HDR.LN> = SPACE(65)

          BEGIN CASE
          CASE SEL.SORTBY   = 'Customer'
             HDG<1,HDR.LN>  = 'Cust #  Customer Name.............'
             HDG<1,HDR.LN> := SPACE(63)
          CASE SEL.SORTBY   = 'Product'
             HDG<1,HDR.LN> := 'Product Description' "L#31"
          CASE SEL.SORTBY   = 'Zip Code'
             HDG<1,HDR.LN> := 'Zip.. Price Line' "L#31"
          CASE SEL.SORTBY   = '3 Digit Zip'
             HDG<1,HDR.LN> := 'Zip-Price Line' "L#31"
          CASE SEL.SORTBY   = 'Line (price)'
             HDG<1,HDR.LN> := 'Price Line' "L#31"
          CASE SEL.SORTBY   = 'Branch'
             HDG<1,HDR.LN>  = SPACE(97)
          CASE SEL.SORTBY   = 'Branch by Price Line'
             HDG<1,HDR.LN>  = SPACE(36)
             HDG<1,HDR.LN> := 'Price Line Description' "L#51":SPACE(10)
          CASE SEL.SORTBY   = 'Cust PO#'
             HDG<1,HDR.LN>  = 'Cust #  Customer Name.............'
             HDG<1,HDR.LN> := SPACE(16):'Cust PO#.......':SPACE(47)
             POSP = 16
          CASE SEL.SORTBY[1,11] = 'Customer by'
             HDG<1,HDR.LN>  = 'Cust # Customer Name.............':SPACE(64)
          CASE OTHERWISE
             HDG<1,HDR.LN> := SEL.SORTBY "L#31"
          END CASE

          HDG<1,HDR.LN>    := END.HD

          RETURN
*-------------------------------------------------------------------------*
PRT.ONE:  *** Print one line item to the report...

          IF DETAIL THEN
             ID     = FIELD(TID,'~',3)
             SHP.DT = TMP<4,1>
             CN     = FIELD(TID,'~',2)
             PROV   = TMP<4,2>
             CSOV   = TMP<4,3>
             SNS    = RAISE(TMP<4,4>)
             IF PO.FLAG THEN
                CUST.PO = TMP<4,5>
             END
             WHSE   = TMP<4,6>
             IF PROV THEN PROV = '*' ELSE PROV = ' '
             IF CSOV THEN CSOV = '*' ELSE CSOV = ' '
             IVNO   = FIELD(ID,'.',1):'.':FIELD(ID,'.',2)"R%3"
          END ELSE
             CN     = FIELD(TID,"~",2)
          END

          PUM   = TMP<3>
          PN    = TMP<2,1>
          EXT   = TMP<1,1>
          CEXT  = TMP<1,2>
          PQTY  = TMP<1,3>

          *** Only print customer name and number if it is a new customer
          *** OR if we are not sorting by one of the customer options...
          IF PREV.CN # CN OR SEL.SORTBY[1,3] # 'Cus' THEN
             IF SEL.SORTBY[1,3] = 'Cus' AND NOT(PO.FLAG) THEN
                IF CCT>1 OR NOT(DETAIL) THEN
                   GOSUB PRT.CTOL
                END ELSE
                   CCT  = 0
                   CTOL = ''
                END
                IF ITEM.CT > 0 AND PG.BRK = 'Yes' THEN PRINT CHAR(12)
             END

             MATREAD CUS FROM CUSFILE,CN ELSE MAT CUS = ''
             IF DETAIL THEN
                PRNT.CN = "&":CN
                PRINT PRNT.CN                 "L#7":' ':
                PRINT CUS(1)                  "L#26":'  ':
             END
             PREV.CN    = CN

          *** If the customer is not new just indent (don't print the name)
          END ELSE
             IF DETAIL THEN
                PRINT ''                      "L#34":'  ':
             END
          END

          CCT += 1

          MATREAD PRD FROM PRDFILE,PN ELSE MAT PRD = ''
          DESC = PRD(1)
          CONVERT VM TO ' ' IN DESC

          IF DETAIL THEN
             PRINT IVNO                        "L#14":'  ':
             IF PO.FLAG THEN
                PRINT CUST.PO                  "L#15 ":
             END
             PRINT WHSE                        "R#4":'  ':
             PRINT OCONV(SHP.DT,'D2/')         "L#8":'  ':
             PRINT "^":PN                      "L#8":" ":
             PRINT DESC                        "L#31":'   ':
             PRINT.PQTY = (PQTY"R2")+0
             PRINT PRINT.PQTY                  "R#10":PUM "L#2":' ':
             IF COSTS # 'O' THEN
                PRINT OCONV(EXT,'MR2')         "R#16":
             END ELSE
                PRINT OCONV(CEXT,'MR2')        "R#16":
             END
             PRINT PROV                        "L#1":' ':
             IF COSTS = 'Y' AND COST.TYPE THEN
                PRINT OCONV(CEXT,'MR2')        "R#16":
                PRINT CSOV                     "L#1":' ':

                *** Gross Profit Dollars...
                GPD = EXT - CEXT
                PRINT OCONV(GPD,'MR2')         "R#13":' ':

                IF EXT + 0 = 0 THEN
                   GP% = 0
                END ELSE
                   GP% = (EXT-CEXT)/EXT*100
                END
                PRINT GP%                      "R1#7":'%'
             END ELSE PRINT

             *** Display the serial numbers...
             SN.CT     = DCOUNT(SNS<1,1>,SVM)
             IF PO.FLAG THEN
                SSPACE = 79
             END ELSE
                SSPACE = 64
             END
             FOR SNUM  = 1 TO SN.CT
                PRINT SPACE(SSPACE):' SN# : ':
                PRINT SNS<1,1,SNUM>            "L#30"
             NEXT SNUM
          END

*** Increment our Totals...
          ITEM.CT   += 1

          CTOL<1,1> += EXT
          CTOL<1,2> += CEXT
          CTOL<1,3> += PQTY
          LOCATE PUM IN CTOL<1,4> SETTING POS ELSE CTOL<1,4,POS> = PUM

          BTOL<1,1> += EXT
          BTOL<1,2> += CEXT
          BTOL<1,3> += PQTY
          LOCATE PUM IN BTOL<1,4> SETTING POS ELSE BTOL<1,4,POS> = PUM

          STOL<1,1> += EXT
          STOL<1,2> += CEXT
          STOL<1,3> += PQTY
          LOCATE PUM IN STOL<1,4> SETTING POS ELSE STOL<1,4,POS> = PUM

          GTOL<1,1> += EXT
          GTOL<1,2> += CEXT
          GTOL<1,3> += PQTY
          LOCATE PUM IN GTOL<1,4> SETTING POS ELSE GTOL<1,4,POS> = PUM

          RETURN
*-------------------------------------------------------------------------*
PRT.STOL: *** Display the subtotal lines

          IF PREV.TID # '@@@' THEN
             ***Check to see if we are in detail mode
             IF DETAIL THEN
                PRINT SPACE(107):SPACE(POSP):'      ===========':
             END ELSE
                PRINT SPACE(94):SPACE(POSP):'      ===========':
             END
             IF COSTS # 'O' THEN
                PRINT ' ================ ':
             END

             IF COST.TYPE THEN
                IF COSTS = 'O' THEN
                   PRINT ' ================'
                END ELSE
                   PRINT ' ================  =============  ======='
                END
             END ELSE PRINT

             ***Check to see if we are in detail mode
             IF DETAIL THEN
                IF SEL.SORTBY[1,3] # 'Cus' AND SEL.SORTBY # 'Product' THEN
                   FLAG = 1
                   PREV.TID = TRIM(PREV.TID)
                   LN       = LEN(PREV.TID)
                   DASHES   = 8 - LN
                   PREV.ID = PREV.TID:' ':STR('-',DASHES):'-- '

*                  PRINT SPACE(87):SPACE(POSP):'Total for ':PREV.ID"L#12":
                   PRINT SPACE(89):SPACE(POSP):'Total for ':PREV.ID"L#12":

                END ELSE
                   BEGIN CASE
                   CASE BUDGET.SORT
                      STR = 'Total for ':PREV.BUDG"L#12":' ----------'
                      PRINT SPACE(POSP+8):STR"R#103":
                   CASE COMMODITY.SORT
                      STR = 'Total for ':PREV.COM.CD"L#12":' ----------'
                      PRINT SPACE(POSP+8):STR"R#103":
                   CASE SELL.SORT
                      STR = 'Total for ':PREV.SELL"L#12":' ----------'
                      PRINT SPACE(POSP+8):STR"R#103":
                   CASE PRODUCT.SORT
                      STR = 'Total for ':PREV.PROD"L#20":' ----------'
                      PRINT SPACE(POSP+8):STR"R#103":
                   CASE OTHERWISE
                      PRINT SPACE(95):SPACE(POSP):'Total ----------':
                   END CASE
                END

             *** If not in detail mode, we must be in summary mode
             END ELSE
                BEGIN CASE
                CASE BUDGET.SORT
                   IF PREV.BUDG = '' THEN PREV.BUDG = 'Blank Budget Group'
                   PRNT.CN = "&":CN
                   PRINT PRNT.CN        "L#7":' ':
                   PRINT CUS(1) "L#30":SPACE(POSP):' ------ ':
                   PRINT PREV.BUDG"L#30":SPACE(22):
                CASE COMMODITY.SORT
                   IF PREV.COM.CD = '' THEN
                      PREV.COM.CD = 'Blank Commodity Code'
                   END
                   PRNT.CN = "&":CN
                   PRINT PRNT.CN                      "L#7":' ':
                   PRINT CUS(1)                       "L#30":
                   PRINT SPACE(POSP):' ------ ':
                   PRINT PREV.COM.CD                  "L#30":SPACE(22):
                CASE SELL.SORT
                   IF PREV.SELL = '' THEN PREV.SELL = 'Blank Sell Group'
                   PRNT.CN = "&":CN
                   PRINT PRNT.CN        "L#7":' ':
                   PRINT CUS(1) "L#30":SPACE(POSP):' ------ ':
                   PRINT PREV.SELL"L#30":SPACE(22):
                CASE PRODUCT.SORT
                   IF PREV.PROD = '' THEN PREV.PROD = 'Blank Product'
                   PRNT.CN = "&":CN
                   PRINT PRNT.CN        "L#7":' ':
                   PRINT CUS(1) "L#30":SPACE(POSP):' ------ ':
                   PRINT PREV.PROD"L#30":SPACE(22):
                CASE SEL.SORTBY[1,3] = 'Cus'
                   LN.ID = TRIM(FIELD(PREV.TID,'@',3))
                   IF SEL.SORTBY = 'Customer' AND SLCT = 'Buy Line' THEN
                      READV PDESC FROM BLNEFILE,LN.ID,1 ELSE PDESC = ''
                   END ELSE
                      READV PDESC FROM PLNEFILE,LN.ID,1 ELSE PDESC = ''
                   END
                   IF TRIM(PDESC) = '' THEN PDESC = '* Not Found *'
                   SPCR  = ' ------ '
                   PRNT.CN = "&":CN
                   IF NOT(PO.FLAG) THEN
                      PRINT PRNT.CN                   "L#7":' ':
                      PRINT CUS(1)                    "L#30":
                      PRINT SPACE(POSP):SPCR:
                      PRINT PDESC                     "L#31":SPACE(21):
                   END ELSE
                      PRINT PRNT.CN                   "L#7":' ':
                      PRINT CUS(1)                    "L#30":
                      PRINT SPACE(12):
                      PRINT PREV.TID                  "L#15":SPCR:
                      PRINT PDESC                     "L#31":SPACE(9):
                   END
                CASE SEL.SORTBY = 'Product'
                   PRINT SPACE(69):DESC               "L#30":' ':
                CASE OTHERWISE
                   PRINT SPACE(47):
                   PRINT 'SubTotal For -----  '       "L#20":
                   PRINT PREV.TID                     "L#30":' ':
                END CASE
             END

             IF STOL<1,4,2> = '' THEN TUM = STOL<1,4> ELSE TUM = '**'

             PRINT.STOL = (STOL<1,3>"R2")+0
             PRINT PRINT.STOL                "R#11":
             PRINT TUM                       "L#2":

             IF COSTS # 'O' THEN
                PRINT OCONV(STOL<1,1>,'MR2') "R#17":'  ':
             END ELSE
                PRINT OCONV(STOL<1,2>,'MR2') "R#17":'  ':
             END

             IF COSTS  = 'Y' AND COST.TYPE THEN

                PRINT OCONV(STOL<1,2>,'MR2') "R#16":'  ':

                GPD    = STOL<1,1>-STOL<1,2>

                PRINT OCONV(GPD,'MR2')       "R#13":' ':

                IF STOL<1,1>+0=0 THEN
                   GP% = 0
                END ELSE
                   GP% = (STOL<1,1>-STOL<1,2>)/STOL<1,1>*100
                END

                PRINT GP%                    "R1#7":'%'
             END ELSE
                PRINT
             END

             *** Page Breaks after each total...
             IF PG.BRK = 'Yes' THEN
                IF FLAG THEN
                   PRINT CHAR(12)
                   FLAG = ''
                END ELSE
                   PRINT
                END
             END ELSE
                PRINT
             END
             STOL  = ''
          END
          PREV.TID = TID1

          RETURN
*-------------------------------------------------------------------------*
PRT.BTOL: *** Print the Branch Totals...

          IF PREV.TD2 # '@@@' THEN
             IF DETAIL THEN
                IF SUB.FLAG THEN
                   PRINT SPACE(107):SPACE(POSP):
                   PRINT '      =========== ================ ':
                  IF COST.TYPE THEN
                      PRINT ' ================  =============  ======='
                  END ELSE PRINT

                   PREV.TD2 = TRIM(PREV.TD2)
                   LN       = LEN(PREV.TD2)
                   DASHES   = 8 - LN
                   PREV.SRT = PREV.TD2:' ':STR('-',DASHES):'-- '

*                  PRINT SPACE(87):SPACE(POSP):'Total for ':PREV.SRT"L#12":
                   PRINT SPACE(89):SPACE(POSP):'Total for ':PREV.SRT"L#12":
                END ELSE PRINT
             END ELSE
                PREV.TD2 = TRIM(PREV.TD2)
                *GOSUB GET.DESC
                PRT.DESC = PREV.TD2
                PRINT '' "L#30":SPACE(POSP):' ------ ':PRT.DESC"L#30":
                PRINT SPACE(30):
             END

             IF BTOL<1,4,2> = '' THEN TUM = BTOL<1,4> ELSE TUM = '**'

             PRINT.BTOL = (BTOL<1,3>"R2")+0
             PRINT PRINT.BTOL                "R#11":
             PRINT TUM                       "L#2":

             IF COSTS # 'O' THEN
                PRINT OCONV(BTOL<1,1>,'MR2') "R#17":'  ':
             END ELSE
                PRINT OCONV(BTOL<1,2>,'MR2') "R#17":'  ':
             END
             IF COSTS = 'Y' AND COST.TYPE THEN

                PRINT OCONV(BTOL<1,2>,'MR2') "R#16":'  ':

                GPD   = BTOL<1,1>-BTOL<1,2>

                PRINT OCONV(GPD,'MR2')       "R#13":'  ':

                IF BTOL<1,1> + 0 = 0 THEN
                   GP% = 0
                END ELSE
                   GP% = (BTOL<1,1>-BTOL<1,2>)/BTOL<1,1>*100
                END

                PRINT GP% "R1#6":'%'
             END ELSE PRINT

             PRINT
             BTOL  = ''
          END

          PREV.TD2 = TID2

          RETURN
*-------------------------------------------------------------------------*
PRT.CTOL: *** Print the Customer Totals...

          IF PREV.CN = '@@@' THEN RETURN
          IF SUB.FLAG THEN
             IF DETAIL THEN PRINT SPACE(107): ELSE PRINT SPACE(94):
             PRINT SPACE(POSP):'      ----------- ----------------':

             IF COST.TYPE AND COSTS #'O' THEN
                PRINT '  ----------------  -------------  -------'
             END ELSE PRINT

*** Pad the Customer name with dashes, to fill a string length of 30...
             C1     = CUS(1)[1,30]
             LN     = LEN(C1)
             DASHES = 30 - LN
             CUST   = C1:' ':STR('-',DASHES)

             WRK    = '** Subtotal for : ':CUST:' '
             IF DETAIL THEN PRINT SPACE(61):SPACE(POSP):WRK: ELSE PRINT SPACE(48):SPACE(POSP):WRK:

             IF CTOL<1,4,2> = '' THEN TUM = CTOL<1,4> ELSE TUM = '**'

             PRINT.CTOL = (CTOL<1,3>"R2")+0
             PRINT PRINT.CTOL                "R#11":
             PRINT TUM                       "L#2":

             IF COSTS # 'O' THEN
                PRINT OCONV(CTOL<1,1>,'MR2') "R#17":'  ':
             END ELSE
                PRINT OCONV(CTOL<1,2>,'MR2') "R#17":'  ':
             END

             IF COSTS = 'Y' AND COST.TYPE THEN
                PRINT OCONV(CTOL<1,2>,'MR2') "R#16":'  ':
                GPD = CTOL<1,1>-CTOL<1,2>
                PRINT OCONV(GPD,'MR2')       "R#13":' ':
                IF CTOL<1,1> + 0 = 0 THEN
                   GP% = 0
                END ELSE
                   GP% = (CTOL<1,1>-CTOL<1,2>)/CTOL<1,1>*100
                END
                PRINT GP%                    "R1#7":'%'
             END ELSE PRINT

             PRINT
             PRINT
          END ELSE
             PRINT
          END

          CTOL = ''
          CCT  = 0

          RETURN
*-------------------------------------------------------------------------*
PRT.GTOL: *** Print the Grand Totals...
          IF DETAIL THEN PRINT SPACE(108):SPACE(POSP): ELSE PRINT SPACE(95):SPACE(POSP):
          PRINT '   ============= ================ ':
          IF COST.TYPE THEN
             PRINT ' ================  =============  ======='
          END ELSE PRINT

          IF GTOL<1,4,2> = '' THEN TUM = GTOL<1,4> ELSE TUM = '**'

          IF DETAIL THEN PRINT SPACE(95):SPACE(POSP): ELSE PRINT SPACE(82):SPACE(POSP):
          PRINT.GTOL = (GTOL<1,3>"R2")+0
          PRINT 'Grand Total ---- ':PRINT.GTOL "R#10":
          PRINT TUM                           "L#2":

          IF COSTS # 'O' THEN
             PRINT OCONV(GTOL<1,1>,'MR2')     "R#17":'  ':
          END ELSE
             PRINT OCONV(GTOL<1,2>,'MR2')     "R#17":'  ':
          END

          IF COSTS  = 'Y' AND COST.TYPE THEN
             PRINT OCONV(GTOL<1,2>,'MR2')     "R#16":'  ':
             GPD    = GTOL<1,1>-GTOL<1,2>
             PRINT OCONV(GPD,'MR2')           "R#13":' ':
             IF GTOL<1,1> + 0 = 0 THEN
                GP% = 0
             END ELSE
                GP% = (GTOL<1,1>-GTOL<1,2>)/GTOL<1,1>*100
             END
             PRINT GP%                        "R1#7":'%'
          END ELSE PRINT

          RETURN
*-------------------------------------------------------------------------*
SEL.IDS:  *** Select our AR Records and Filter through them...

          SORTBYS = ''
          TID.CT = ''

          *** We'll Select AR records first for Invoices and then for
          *** Transfers...
          FOR CODE.INDX = 1 TO CD.CT
             *** JLI.CODE will be 1 for Invoice Code...
             *** JLI.CODE will be 5 for Transfer Code...
             JLI.SELECT MESS,SD,ED,,JLI.CODES<CODE.INDX>

             NXT.CD = JLI.CODES<CODE.INDX>

             LOOP
                READNEXT ID ELSE EXIT

                *** Break out the values for this record...
                OID  = FIELD(ID,'.',1)
                INVN = FIELD(ID,'.',2) + 0

                *** If we're on the JLI.CODE - Transfer Code, and
                *** our invoice number is an even number...
                IF NXT.CD = TRANS.CD AND MOD(INVN,2) = 0    THEN CONTINUE

                MATREAD LED FROM LEDFILE,OID                ELSE CONTINUE
                LOCATE INVN IN LED(8)<1> SETTING GEN        ELSE CONTINUE

                *** Get the QSIGN for this order...
                OE.GET.QSIGN QSIGN,OID,GEN

                SHIP.BR = LED(2)<1,GEN,2>

                IF SBR = 'Pricing' THEN
                   BR  = LED(2)<1,GEN,1>
                END ELSE
                   BR  = SHIP.BR
                END

                LOCATE BR IN BRCHS<1> SETTING XX            ELSE CONTINUE

                *** check for consignment transfer and ignore
                IF LED(110)<1,1> = 'S'                      THEN CONTINUE

                *** Check the Direct Shipments Option (If this is null,
                *** it isn't a Direct)...
                ISDIR = LED(33)<1,GEN>

                BEGIN CASE
                CASE SHOW.DIR = 'Include';NULL
                CASE SHOW.DIR = 'Exclude' AND ISDIR # ''
                   CONTINUE
                CASE SHOW.DIR = 'Only' AND ISDIR = ''
                   CONTINUE
                END CASE

                *** Filter against the Customer Consignment option...
                IS.CCSN = (LED(110)<1,1>='B')

                * Handle Customer Consigned Items
                BEGIN CASE
                CASE SHOW.CCSN = "Include"; NULL
                CASE SHOW.CCSN = "Exclude"
                   IF SHOW.VENCUST = "Exclude" THEN
                      IF IS.CCSN THEN CONTINUE
                   END
                CASE OTHERWISE
                   IF SHOW.VENCUST = "Exclude" THEN
                      IF (IS.CCSN AND (LED(5)<1,GEN>#CUS.ID)) THEN CONTINUE
                   END
                END CASE

                *** Filter against the User's 'Additional Selects'...
                IF FILTER.FLAG THEN
                   FILTER.SELECT SKIP.FLAG,OID,GEN,FITEM
                   IF SKIP.FLAG THEN CONTINUE
                END

                LDIDS = LED(48)<1,GEN>
                LD.CT = DCOUNT(LDIDS,SVM)
*** FOR each Line Item on the order...
                FOR LDN = 1 TO LD.CT
                   SRT.BRK = ''
                   LDID = LDIDS<1,1,LDN>
                   *** Build the LD array for the next LDID...
                   LD.GET LDID

                   IF CURR.FLG THEN
                      CONV.CURR.LD TGT,GEN
                   END

                   *** Get the total ship qty...
                   QTY = (SUM(LD(5)<1,GEN>) + SUM(LD(6)<1,GEN>)) * QSIGN

                   *** Filter against the Credits option...
                   *** handle the Adjustment in Check.Type where it will be
                   *** excluded if it is not VendorConsignment
                   IF OID[1,1] # 'A' THEN
                      BEGIN CASE
                      CASE SEL.CREDS = 'O'
                         IF QTY >= 0 THEN CONTINUE
                      CASE SEL.CREDS = 'E'
                         IF QTY < 0 THEN CONTINUE
                      END CASE
                   END

                   *** Read in any Kit Components...
                   KIT.COMPS = LD(31)

                   *** If they ONLY want to see Kit Components but
                   *** this product is not a Kit then skip it...
                   IF SHOW.KIT.COMPS = 'Only' AND NOT(KIT.COMPS) THEN
                      CONTINUE
                   END

                   *** If this product is a Kit and they want to see
                   *** the Kits as Components we'll need to filter
                   *** against each Component...
                   IF FILTER.COMPS AND KIT.COMPS THEN
                      *** Save our Kit Qty since we'll be resetting
                      *** our QTY variable for each Kit Component...
                      KIT.QTY = QTY
                      *** Count the Components in our Kit...
                      CMP.CT = DCOUNT(KIT.COMPS,VM)
                      FOR CMP = 1 TO CMP.CT
                         PN  = KIT.COMPS<1,CMP>
                         *** Go filter against this Product...
                         GOSUB FILTER.PRODUCT
                      NEXT CMP
                   *** Otherwise we're just dealing with the Line Item...
                   END ELSE
                      PN = LD(1)
                      *** Go filter against this Product...
                      GOSUB FILTER.PRODUCT
                   END
                NEXT LDN
             REPEAT
          NEXT CODE.INDX

          RETURN
*-------------------------------------------------------------------------*
FILTER.PRODUCT: *** Filter against the one Product Number we come in with

          IF NOT(NUM(PN)) OR PN = ''                   THEN RETURN

          LOCATE PN IN AR.PNS<1> SETTING NOTHING       THEN RETURN

          MATREAD PRD FROM PRDFILE,PN ELSE MAT PRD = ''

          *** Filter against any 'Select by' entities selected...
          IF SLIST THEN
             TEMP.SLCT          = SLCT
             TEMP.SLIST         = SLIST
             CHECKING.SELECT.BY = YES
             *** Go use our generic routine for filtering against the
             *** Select criteria...
             GOSUB CHECK.SELECT

             *** If the product didn't meet the Select by criteria then
             *** we can't include it...
             IF NOT(PRODUCT.OK)                        THEN RETURN
          END

          *** Filter against any 'Additional Select' entities selected...
          IF SLIST2 THEN
             TEMP.SLCT          = ADDL.SLCT
             TEMP.SLIST         = SLIST2
             CHECKING.SELECT.BY = NO
             *** Go use our generic routine for filtering against the
             *** Select criteria...
             GOSUB CHECK.SELECT

             *** If the product didn't meet the Additional Select by
             *** criteria then we can't include it...
             IF NOT(PRODUCT.OK)                        THEN RETURN
          END

          IF SLCT = '' THEN SLCT = 'Price Line'

          ** If we are sorting by branch then we sort by priceline
          ** after sorting by branch.  We make room for the full
          ** full priceline desc on the report, so we need to
          ** sort by the full description.
          PRC.LN = PRD(9)
          READV PRC.LN.DESC FROM PLNEFILE,PRC.LN,1 ELSE PRC.LN.DESC = ''
          IF SEL.SORTBY[1,6] = 'Branch' AND PRC.LN.DESC # '' THEN
             SRT.BRK = SRT.BRK:': ':PRC.LN.DESC
          END ELSE
             IF SRT.BRK = '' THEN SRT.BRK = PRC.LN
          END

          *** Validate the Product Status...
          STOCK = TRIM(PRD(3))
          LOCATE STOCK IN STAT SETTING J ELSE RETURN

          BEGIN CASE
          CASE FILTER.COMPS AND KIT.COMPS
             *** If we need to show Kits as Components and this is a Kit...

             *** Get each location type for this Component...
             SHIP.DATE = LED(9)<1,GEN>

             CHK.ID  = PN:'~':BR:'~':SHIP.DATE'R%5':'~'
             CHK.ID := OID:'~':INVN:'~':LDID

             ROOT    = CHK.ID:'~'

             LOOP
                BSCAN PSUB.ID FROM PSUBFILE,ROOT USING '&INDEX&' ELSE EXIT
                ROOT = ''

                IF FIELD(PSUB.ID,'~',1,6) # CHK.ID THEN EXIT
                IF FIELD(PSUB.ID,'~',9) # CMP THEN CONTINUE

                TYP  = FIELD(ID,'~',7,1)

                *** Go validate the location type and the Vendor
                *** Consignment option...
                TYP.LOC = FIELD(ID,'~',7)
                GOSUB CHECK.TYPE

                *** If the Component passed that last filter...
                READ PREC FROM PSUBFILE,PSUB.ID ELSE PREC = ''
                IF ADD.OK THEN
                   *** Get the Spoilage Factor...
                   SPOILAGE = (1+LD(39)<1,CMP>/1000)
                   *** Component Qty * Number of Kits * Spoilage
                   QTY      = INT(LD(30)<1,CMP> * KIT.QTY * SPOILAGE)

                   *** Go add a record for this Product...
                   GOSUB ADD.ID
                END
             REPEAT
          CASE OTHERWISE
             TYP.LOCS   = LD(7)<1,GEN>
             LOC.CT     = DCOUNT(TYP.LOCS,SVM)

             *** Filter the Product Type...
             FOR JJ     = 1 TO LOC.CT
                TYP     = FIELD(TYP.LOCS<1,1,JJ>,'~',1)

                *** Go validate the location type and the Vendor
                *** Consignment option...
                TYP.LOC = TYP.LOCS<1,1,JJ>
                GOSUB CHECK.TYPE

                *** If the Product passed that last filter...
                IF ADD.OK THEN
                   QTY  = (LD(5)<1,GEN,JJ> + LD(6)<1,GEN,JJ>) * QSIGN
                   GOSUB ADD.ID
                END
             NEXT JJ
          END CASE

          RETURN
*-------------------------------------------------------------------------*
CHECK.SELECT: *** Filter against the 'Select by' OR 'Additional Select'
              *** entities...

          PRODUCT.OK = NO

          BEGIN CASE
          *** Filter against product list
          CASE TEMP.SLCT = 'Product'
             LOCATE PN IN TEMP.SLIST<1> SETTING XX      ELSE RETURN
             IF CHECKING.SELECT.BY THEN SRT.BRK = PN
          *** Filter against any Price Lines that have been selected...
          CASE TEMP.SLCT = 'Price Line'
             PRC.LN      = PRD(9)
             LOCATE PRC.LN IN TEMP.SLIST<1> SETTING XX  ELSE RETURN
             IF CHECKING.SELECT.BY THEN SRT.BRK = PRC.LN
          *** Filter against any Buy Lines selected
          CASE TEMP.SLCT = 'Buy Line'
             BUY.LN      = PRD(12)
             LOCATE BUY.LN IN TEMP.SLIST<1> SETTING XX  ELSE RETURN
             IF CHECKING.SELECT.BY THEN SRT.BRK = BUY.LN
          *** Filter against any Sell Groups that have been selected...
          CASE TEMP.SLCT = 'Sell Group'
             SV.SEL.GRP = ''
             GO.FLAG    = NO
             PRD.BR.GET.VAL LED(2)<1,GEN,1>,PN,24,SEL.GRP
             RUN.THR = DCOUNT(SEL.GRP, VM)
             FOR X = 1 TO RUN.THR
                LOCATE SEL.GRP<1,X> IN TEMP.SLIST<1> SETTING XX ELSE CONTINUE
                GO.FLAG    = YES
                SV.SEL.GRP = SEL.GRP<1,X>
                IF CHECKING.SELECT.BY THEN SRT.BRK = SEL.GRP<1,X>
                EXIT
             NEXT X
             IF GO.FLAG = NO THEN RETURN
          *** Filter against any Buy Groups that have been selected...
          CASE TEMP.SLCT = 'Buy Group'
             SV.BUY.GRP = ''
             GO.FLAG    = NO
             PRD.BR.GET.VAL LED(2)<1,GEN,1>,PN,23,BUY.GRP
             RUN.THR = DCOUNT(BUY.GRP, VM)
             FOR X = 1 TO RUN.THR
                LOCATE BUY.GRP<1,X> IN TEMP.SLIST<1> SETTING XX ELSE CONTINUE
                GO.FLAG    = YES
                SV.BUY.GRP = BUY.GRP<1,X>
                IF CHECKING.SELECT.BY THEN SRT.BRK = BUY.GRP<1,X>
                EXIT
             NEXT X
             IF GO.FLAG = NO THEN RETURN
          *** Filter against any American Standard Categories that have been selected...
          CASE TEMP.SLCT = 'Amer Std Category'
            AMSTD = PRD(200)
            LOCATE AMSTD IN TEMP.SLIST<1> SETTING XX  ELSE RETURN
            IF CHECKING.SELECT.BY THEN SRT.BRK = AMSTD
            IF GO.FLAG = NO THEN RETURN
          *** Filter against any Prod Slct Codes...
          CASE TEMP.SLCT = 'Product Select Code'
             CCODE = PRD(19)
             LOCATE CCODE IN TEMP.SLIST<1> SETTING XX   ELSE RETURN
             IF CHECKING.SELECT.BY THEN SRT.BRK = CCODE
          END CASE
          PRODUCT.OK = YES
          RETURN
*-------------------------------------------------------------------------*
CHECK.TYPE: *** Filter against the Loc. Type and the Vendor Consign. option
            * There are 3 types of consignment:
            * Vendor Consignment: Distributor has item on consignment from
            * Vendor
            ***************
            * Customer Consignment: Customer has item on consignment from
            * Distributor
            * *************
            * Vendor-Customer Consignment: Customer gets an item from
            * Distributor that Dist had on consignment from Vendor
            ***************
            * (In PROD.DYNAM attr 8 you can see the TYP.LOC values used in
            * this subroutine - they are location types)

          ADD.OK = YES

          IF SEL.TYPS THEN
             LOCATE TYP[1,1] IN SEL.TYPS<1> SETTING POS ELSE
                ADD.OK = NO
                RETURN
             END
          END

          IS.VC.ITEM  = NO
          TYP.LEN = LEN(TYP)

          * Check for vendor/customer consignment
          IF TYP[1,1] = 'C' THEN
             VC.NUM = FIELD(FIELD(TYP.LOC,"~",2),"|",2)
             IS.VC  = (VC.NUM # "")
          END ELSE
             VC.NUM = ''
             IS.VC  = ''
          END

          * Check the Vend Consign Shipments Option
          IS.VCSN  = (TYP[1,1] = 'S' AND TYP.LEN > 1)
          IS.STOCK = YES

          IF (IS.VC) OR (IS.VCSN) OR (IS.CCSN) THEN IS.STOCK = NO

          * Handle items that are Vendor to Customer Consigned.
          IF IS.VC THEN
             BEGIN CASE
             CASE SHOW.VENCUST = "Exclude"; ADD.OK = NO
             CASE SHOW.VENCUST = "One"
                IF (VC.NUM # VEN.ID)        THEN ADD.OK = NO
                IF (LED(5)<1,GEN> # CUS.ID) THEN ADD.OK = NO
             END CASE
          END ELSE
             IF IS.CCSN THEN
                BEGIN CASE
                CASE (SHOW.CCSN = "Exclude"); ADD.OK = NO
                CASE (SHOW.CCSN = "One")
                   IF (LED(5)<1,GEN> # CUS.ID) THEN ADD.OK = NO
                END CASE
             END
          END

          * Handle items that are Vendor Consigned.
          IF IS.VCSN THEN
             BEGIN CASE
             CASE SHOW.VCSN = "Include"; NULL
             CASE SHOW.VCSN = 'Exclude'; ADD.OK = NO
             * Selecting on a Specific Consignment Vendor...
             CASE OTHERWISE
                IF (TYP[2,99] # VEN.ID) THEN ADD.OK = NO
             END CASE
          END ELSE
             * If we're dealing with an adjustment and the adjustment
             * is not for vendor consigned material then exclude from
             * rpt
             IF OID[1,1] = 'A' THEN ADD.OK = NO
          END

          * Check to see if Stock items should be excluded.
          IF IS.STOCK THEN
             IF (SHOW.STOCK = "Exclude") THEN ADD.OK = NO
          END

          IF IS.CRED THEN
             IF SEL.CREDS = "O" THEN
                IF QTY > 0 THEN ADD.OK = NO
             END
          END ELSE
             IF QTY < 0 THEN ADD.OK = NO
          END

          RETURN
*-------------------------------------------------------------------------*
ADD.ID:   *** Create a Temp Id for this record and store some data...

          ID   = OID:'.':LED(8)<1,GEN>:'.':LDID
          * Since there may be more than one Product per Line Item when
          * showing Kit Components we need to form unique Id's for each
          * component in the temp file.  We will append the Component
          * after the Line Item ID.
          IF FILTER.COMPS AND KIT.COMPS THEN
             ID := '.':CMP
          END

          SNS  = ''

*** Get the Product's Price info...
          IF FILTER.COMPS AND KIT.COMPS THEN
             IF CURR.FLG THEN
                GOSUB CONV.CURR
             END
             PRC     = PREC<2>; * Sell Price
             PROV    = PREC<6>; * Price Override

             PRD.SER = PREC<9>; * Serial Numbers
          END ELSE
             PRC     = LD(8)<1,GEN>
             PROV    = (LD(9)<1,GEN> # '')
          END

*** Get any Serial Numbers if necessary...
          GET.SNS  = NO
          PRD.BR.GET.VAL SHIP.BR,PN,25,SNS.TYPE

          BEGIN CASE
          *** All Serial Numbers
          CASE SHOW.SNS = 'A'
             IF (SNS.TYPE # 'N' AND SNS.TYPE # '') THEN
                GET.SNS = YES
             END
          *** Inbound Serial Numbers
          CASE SHOW.SNS = 'I'
             IF (SNS.TYPE = 'I' OR SNS.TYPE = 'A' OR SNS.TYPE ='D') THEN
                GET.SNS = YES
             END
          END CASE

          IF GET.SNS THEN
             IF FILTER.COMPS AND KIT.COMPS THEN
                LOCATE PN IN LD(31)<1> SETTING KPOS ELSE KPOS = ""
                SNS = LOWER(LD(83)<1,GEN,KPOS>)
             END ELSE
                SNS = LOWER(LD(32)<1,GEN>)
             END
          END

*** Get the appropriate Cost and Cost Override flag...
          BEGIN CASE
          *** Only COGS are set for Kit Components...
          CASE FILTER.COMPS AND KIT.COMPS
             CST  = PREC<3>
             CSOV = PREC<7>
          *** COMM Cost...
          CASE COST.TYPE = '1'
             CST  = LD(27)<1,GEN>
             CSOV = (LD(28)<1,GEN> # '')
          *** COGS Cost...
          CASE OTHERWISE
             CST  = LD(10)<1,GEN>
             CSOV = (LD(11)<1,GEN> # '')
          END CASE

*** Set up our Tempfile Id...
          READV PRC.LN FROM PRDFILE,PN,9 ELSE PRC.LN = ''
          READV BUY.LN FROM PRDFILE,PN,12 ELSE BUY.LN = ''

          BEGIN CASE
          CASE LEVEL[1,1] = 'B'
             CN   = LED(1)<1,GEN>
          CASE LEVEL[1,1] = 'S'
             CN   = LED(5)<1,GEN>
          CASE LEVEL[1,1] = 'P'
             READV PID FROM CUSFILE,LED(1)<1,GEN>,80 ELSE PID = ''
             IF PID = '' THEN
                CN  = LED(1)<1,GEN>
             END ELSE
                CN  = PID<1,1>
             END
          END CASE

          CUST.PO  = LED(13)<1,GEN>
          SCUST.PO = OCONV(LED(13)<1,GEN>,'MCU')
          READV CSORTBY FROM CUSFILE,CN,8 ELSE CSORTBY = ''
          CSORTBY2 = CSORTBY:'@':CN
          IF SLCT = 'Buy Line' AND SEL.SORTBY = 'Customer' THEN
             CSORTBY = CSORTBY:'@':CN:'@':BUY.LN
          END ELSE
             CSORTBY = CSORTBY:'@':CN:'@':PRC.LN
          END
          SHP.DT   = LED(9)<1,GEN>

          *** Set up the TID based on the SEL.SORTBY
          TID = ''
          BEGIN CASE
          CASE SEL.SORTBY[1,6] = 'Branch'
             IF NUM(BR) THEN
                TID    = BR "R#6":'|':SRT.BRK:' '
             END ELSE
                TID    = BR "L#6":'|':SRT.BRK:' '
             END
          CASE PO.FLAG
             TID    = SCUST.PO:' |':CSORTBY2
          CASE SEL.SORTBY = 'Buy Line'
             READV DESC FROM PRDFILE,PN,1 ELSE DESC = ''
             TID    = BUY.LN:' |':DESC<1,1>
          CASE SEL.SORTBY[13,18] = 'Picker'
             TID = LED(66)<1,GEN>
          CASE SEL.SORTBY[1,4] = 'Line'
             READV SEQ FROM PRDFILE,PN,20 ELSE SEQ=''
             TID    = PRC.LN:' |':SEQ
          CASE SEL.SORTBY[1,2] = 'St'
             *Check for non USA zipcode
             ZIP    = LED(75)<1,GEN>
             IF LEN(FIELD(ZIP,'-',1))=5 AND NUM(ZIP[1,5]) THEN ZIP=ZIP[1,5]
             READV ST.CODE FROM ZIPFILE,ZIP,1 ELSE ST.CODE = ''
             TID    = ST.CODE
          CASE SEL.SORTBY[1,14] = 'Product Select'
             READV PSEL.CODE FROM PRDFILE,PN,19 ELSE PSEL.CODE='** NF: ':PN
             TID    = PSEL.CODE
          CASE SEL.SORTBY[1,6] = 'Select'
             READV SEL.CODE FROM CUSFILE,CN,78 ELSE SEL.CODE='** NF: ':CN
             TID    = SEL.CODE
          CASE SEL.SORTBY[1,6] = 'Sell G'
             SEL.GRP = ''
             IF NOT(SV.SEL.GRP) THEN
                PRD.BR.GET.VAL LED(2)<1,GEN,1>,PN,24,SEL.GRP
                SEL.GRP = TRIM(SEL.GRP,VM,'L')<1,1>
             END ELSE
                SEL.GRP = SV.SEL.GRP
             END
             IF NOT(SEL.GRP) THEN SEL.GRP = '** NF: ':PN
             TID    = SEL.GRP
          CASE SEL.SORTBY[1,6] = 'Buy Gr'
             BUY.GRP = ''
             IF NOT(SV.BUY.GRP) THEN
                PRD.BR.GET.VAL LED(2)<1,GEN,1>,PN,23,BUY.GRP
                BUY.GRP = TRIM(BUY.GRP,VM,'L')<1,1>
             END ELSE
                BUY.GRP = SV.BUY.GRP
             END
             IF NOT(BUY.GRP) THEN BUY.GRP = '** NF: ':PN
             TID    = BUY.GRP
          CASE SEL.SORTBY[1,1] = '3'
             IF SEL.CT = 1 THEN
                TID = LED(75)<1,GEN>[1,3]
             END ELSE
                TID = LED(75)<1,GEN>[1,3]:'-':SRT.BRK
             END
          CASE SEL.SORTBY[1,3] = 'Zip'
             TZIP   = LED(75)<1,GEN>
             IF LEN(FIELD(TZIP,'-',1))=5 AND NUM(TZIP[1,5]) THEN TZIP = TZIP[1,5]
             IF SEL.CT < 2 THEN
                TID = TZIP
             END ELSE
                TID = TZIP:'-':SRT.BRK
             END
          CASE SEL.SORTBY = 'Product'
             READV DESC FROM PRDFILE,PN,1 ELSE DESC = ''

             *** Our description might be VM delimited, so we'll remove
             *** the VM's. We use the first 4 lines of the description.
             CONVERT VM TO " " IN DESC
             DESC = DESC[1,143]

             IF SEL.CT = 1 THEN
                TID = DESC:' |':PN
             END ELSE
                TID = DESC:' |':PN:'|':SRT.BRK
             END
          CASE SEL.SORTBY = 'Writer'
             TID    = LED(73)<1,GEN>:' |':CSORTBY
          CASE SEL.SORTBY[1,3] = 'Out'
             TID    = LED(72)<1,GEN>:' |':CSORTBY
          CASE SEL.SORTBY[1,2] = 'In'
             TID    = LED(34)<1,GEN>:' |':CSORTBY
          CASE BUDGET.SORT
             READV BUD.CSORTBY FROM CUSFILE,CN,8 ELSE BUD.CSORTBY = ''
             BUD.GRP = PRD(92)
             TID     = BUD.CSORTBY:' |':BUD.GRP:'|':CN
          CASE COMMODITY.SORT
             READV COM.CSORTBY FROM CUSFILE,CN,8 ELSE BUD.CSORTBY = ''
             READV CM.CODE FROM PRDFILE,PN,14 ELSE CM.CODE = ''
             *** Our record ID will be the CustomerInfo~CommodityCode...
             TID    = COM.CSORTBY:' |':CN:'|':CM.CODE
             *** It will be sorted by Order, Invoice#, Led. Detail ID...
          CASE SELL.SORT
             READV SEL.CSORTBY FROM CUSFILE,CN,8 ELSE SEL.CSORTBY = ''
             SEL.GRP = ''
             IF NOT(SV.SEL.GRP) THEN
                PRD.BR.GET.VAL LED(2)<1,GEN,1>,PN,24,SEL.GRP
                SEL.GRP = TRIM(SEL.GRP,VM,'L')<1,1>
             END ELSE
                SEL.GRP = SV.SEL.GRP
             END
             IF NOT(SEL.GRP) THEN SEL.GRP = '** NF: ':PN
             TID    = SEL.CSORTBY:' |':SEL.GRP:'|':CN
          CASE SEL.SORTBY[1,3] = 'Com'
             READV TID FROM PRDFILE,PN,14 ELSE TID = ' '
          CASE OTHERWISE
             READV DESC FROM PRDFILE,PN,1 ELSE DESC = ''
             TID    = CSORTBY:'|':DESC<1,1>:' |':PN
             IF SEL.CT > 1 THEN
                TID := '|':SRT.BRK
             END
          END CASE

          TID := ' |~':CN
          IF DETAIL THEN TID := '~':ID

          READ TMP FROM TEMPFILE,TID ELSE TMP = ''

          TMP<1,1> += ICONV(OCONV(QTY*PRC,'MR9'),'MR2')
          TMP<1,2> += ICONV(OCONV(QTY*CST,'MR9'),'MR2')

          PRC.LN = PRD(9)
          MATREAD PLNE FROM PLNEFILE,PRC.LN ELSE MAT PLNE = ''
          IF PRD(15) # '' THEN UM.TBL = PRD(15) ELSE UM.TBL = PLNE(3)

          IF SEL.SORTBY = 'Product' THEN
             *** Use the smallest unit of measure to calculate qty sold.
             IQ.TO.ALPHA UM.TBL,PRD(7),UM.TBL<1,1>,QTY,Q1,U1,Q2,U2,ALPHA
          END ELSE
             *** Use the order UOM
             IQ.TO.ALPHA UM.TBL,PRD(7),LD(23),QTY,Q1,U1,Q2,U2,ALPHA
          END

          *** If we get a non-zero qty in Q2, we will display our total
          *** qty in the HIGHEST unit of measure possible... that way
          *** we will avoid any problems if the qty sold was expressed in
          *** multiple units of measure...
          IF Q2 > 0 THEN
             TUM = U2
             IQ.TO.ALPHA UM.TBL,PRD(7),TUM,QTY,Q1,U1,Q2,U2,ALPHA
          END

          PQTY = Q1
          PUM  = U1
          TMP<1,3> += PQTY

          IF NOT(DETAIL) THEN
             * Keep track if this summary record is from multiple PNs&UMs
             LOCATE PN IN TMP<2,1> SETTING POS ELSE
                IF POS < 3 THEN TMP = INSERT(TMP,2,1,POS;PN)
             END
             LOCATE PUM IN TMP<3,1> SETTING POS ELSE
                IF POS < 3 THEN TMP = INSERT(TMP,3,1,POS;PUM)
             END
          END ELSE
             TMP<2,1> = PN
             TMP<3,1> = PUM
             TMP<4,1> = SHP.DT
             TMP<4,2> = PROV
             TMP<4,3> = CSOV
             TMP<4,4> = SNS
             TMP<4,5> = CUST.PO
             TMP<4,6> = LED(2)<1,GEN,2>
          END

          WRITE TMP ON TEMPFILE,TID
          TID.CT = TID.CT + 1

          RETURN
*-------------------------------------------------------------------------*
CONV.CURR:*** Convert the currency...

          IF LED(23)<1,GEN> THEN CONV.DT = LED(23)<1,GEN> ELSE
             CONV.DT = LED(9)<1,GEN>
          END
          XCURR.RATE.GET XRATE,TGT,CONV.DT
          DIV = OCONV(XRATE,'MR4')
          IF DIV+0=0 THEN DIV=1

          PREC<2> = OCONV(PREC<2>,'MR9')/DIV
          PREC<2> = ICONV(PREC<2>,'MR9')
          PREC<6> = OCONV(PREC<6>,'MR9')/DIV
          PREC<6> = ICONV(PREC<6>,'MR9')

          RETURN
*-------------------------------------------------------------------------*
GET.DESC: *** Get description for Branch sort, summary print

          BEGIN CASE
          CASE SLCT = 'Product'
             READV PRT.DESC FROM PRDFILE,PREV.TD2,1 ELSE PRT.DESC = ''
          CASE SLCT = 'Price Line'
             READV PRT.DESC FROM PLNEFILE,PREV.TD2,1 ELSE PRT.DESC = ''
          CASE SLCT = 'Buy Line'
             READV PRT.DESC FROM BLNEFILE,PREV.TD2,1 ELSE PRT.DESC = ''
          CASE SLCT = 'Buy Group' OR SLCT = 'Sell Group'
             READV PRT.DESC FROM PGRPFILE,PREV.TD2,1 ELSE PRT.DESC = ''
          CASE SLCT = 'Product Select Code'
             PRT.DESC = PREV.TD2
          END CASE

          IF PRT.DESC = '' THEN PRT.DESC = '* Not Found *'

          RETURN
*-------------------------------------------------------------------------*
!SMITJR~02/18/10~17:12
